﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataAccess = Microsoft.MSE.Catalog.Module.Data;
using DTO = Microsoft.MSE.Catalog.Contracts;
using System.Xml;
using System.Data.SqlClient;
using System.Data;

namespace Microsoft.MSE.Catalog.Module.Business
{
    public class ChannelManager
    {
        public ChannelManager()
        {

        }

        #region Channel Functions

        public static Guid CreateChannel(DTO.Channel chnl)
        {
            return DataAccess.Channel.CreateChannel(chnl, null, null);
        }

        public static DTO.Channel UpdateChannel(DTO.Channel chnl, SqlTransaction txn, SqlConnection conn)
        {
            #region Change Tracking
            //get list of runtimes affected
            List<DTO.DBEventDataItem> eventData = null;
            try
            {
                //eventData = RuntimeServerManager.ListRuntimeServersForChannelID(chnl.ID, txn, conn);
            }
            catch (System.Exception ex)
            {
                TraceHelper.TraceError("Error collecting affected runtimes in UpdateChannel.  No change notifications will be sent. Error [{0}].", CatalogSvcHelper.GetExceptionDetails(ex));
            }

            #endregion

            chnl = DataAccess.Channel.UpdateChannel(chnl, txn, conn);

            //send notification to affected runtimes
            DataAccess.RepositoryChange.Save(DTO.DBEvents.OperationsUpdated, DTO.DBChangeType.Update, eventData, txn, conn);

            return chnl;
        }

        public static void DeleteChannel(Guid ID)
        {
            DataAccess.Channel.DeleteChannel(ID, null, null);
        }

        public static DTO.Channel GetChannel(Guid ID)
        {
            return DataAccess.Channel.GetChannel(ID, null, null);
        }

        public static DTO.ChannelList ListChannels()
        {
            return DataAccess.Channel.ListChannels( null, null);
        }


        public static DTO.ChannelList ListChannelsForPolicyID(Guid policyID, SqlTransaction txn, SqlConnection conn)
        {
            return DataAccess.Channel.ListChannelsForPolicyID(policyID, txn, conn);
        }

        #endregion

        #region Channel Group functions

        public static DTO.ChannelGroup CreateChannelGroup(DTO.ChannelGroup channelGroup)
        {

            using (SqlConnection conn = CatalogSvcHelper.GetConnection())
            {
                conn.Open();
                SqlTransaction txn = CatalogSvcHelper.GetTransaction(conn, IsolationLevel.Snapshot);

                try
                {

                    channelGroup.ID = DataAccess.Entity.CreateEntityGroup(channelGroup.Name, channelGroup.Description, 7, txn, conn);

                    if (channelGroup.Channels != null)
                    {
                        foreach (DTO.ChannelListElement channel in channelGroup.Channels)
                        {
                            DataAccess.Entity.AssignEntityToEntityGroup(channelGroup.ID, channel.ID, txn, conn);
                        }
                    }

                    if (txn != null) txn.Commit(); //Commit transaction
                }
                catch (Exception)
                {
                    if (txn != null) txn.Rollback(); //Rollback transaction
                    throw;
                }
            } //Connection is disposed here

            return channelGroup;
        }

        public static DTO.ChannelGroup UpdateChannelGroup(DTO.ChannelGroup channelGroup)
        {
            using (SqlConnection conn = CatalogSvcHelper.GetConnection())
            {
                conn.Open();
                SqlTransaction txn = CatalogSvcHelper.GetTransaction(conn, IsolationLevel.Snapshot);

                try
                {

                    DataAccess.Entity.UpdateEntityGroup(channelGroup.ID, channelGroup.Name, channelGroup.Description, txn, conn);


                    List<DTO.ChannelListElement> oldList = DataAccess.Channel.ListChannelsByGroup(channelGroup.ID, txn, conn);
                    /// Delete all items from the old list
                    if (oldList != null)
                    {
                        foreach (DTO.ChannelListElement oldListElement in oldList)
                        {
                            DataAccess.Entity.RemoveEntityFromEntityGroup(channelGroup.ID, oldListElement.ID, txn, conn);
                        }
                    }
                    /// Add all items from the new list
                    if (channelGroup.Channels != null)
                    {
                        foreach (DTO.ChannelListElement newListElement in channelGroup.Channels)
                        {
                            DataAccess.Entity.AssignEntityToEntityGroup(channelGroup.ID, newListElement.ID, txn, conn);
                        }
                    }

                    if (txn != null) txn.Commit(); //Commit transaction
                }
                catch (Exception)
                {
                    if (txn != null) txn.Rollback(); //Rollback transaction
                    throw;
                }
            } //Connection is disposed here

            return channelGroup;
        }

        public static DTO.ChannelGroup GetChannelGroup(Guid ID)
        {
            DTO.ChannelGroup channelGroup = new DTO.ChannelGroup();
            DTO.EntityGroup entityGroup = new DTO.EntityGroup();


            entityGroup = DataAccess.Entity.GetEntityGroup(ID, null, null);

            channelGroup.ID = entityGroup.ID;
            channelGroup.Name = entityGroup.Name;
            channelGroup.Description = entityGroup.Description;

            channelGroup.Channels = ListChannelsByGroup(ID);


            return channelGroup;
        }

        public static List<DTO.ChannelListElement> ListChannelsByGroup(Guid entityGroupID)
        {
            return DataAccess.Channel.ListChannelsByGroup(entityGroupID, null, null);
        }

        #endregion
    }
}
